package yz.cp.back.admin.controller;


import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import lombok.extern.slf4j.Slf4j;
import org.quartz.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Pageable;
import org.springframework.data.web.PageableDefault;
import org.springframework.web.bind.annotation.*;
import yz.cp.back.common.base.BaseController;
import yz.cp.back.common.constant.CommonConstant;
import yz.cp.back.common.res.ApiException;
import yz.cp.back.common.res.ApiResult;
import yz.cp.back.common.utils.PageKit;
import yz.cp.back.s.entity.SysQuartzJob;
import yz.cp.back.s.service.ISysQuartzJobService;

import java.util.List;

/**
 * 定时任务管理接口
 * @author xukk
 */
@Slf4j
@RestController
@RequestMapping("/web/quartzJob")
public class QuartzJobController extends BaseController {

    @Autowired
    private ISysQuartzJobService quartzJobService;

    @Autowired
    private Scheduler scheduler;

    /**
     * 获取所有定时任务
     * @param pageable
     * @return
     */
    @RequestMapping(value = "/getAllByPage",method = RequestMethod.GET)
    public ApiResult getAll(@PageableDefault Pageable pageable){
        QueryWrapper<SysQuartzJob> wrapper=new QueryWrapper<>();
        IPage<SysQuartzJob> data = quartzJobService.page(PageKit.buildPage(pageable,wrapper),wrapper);
        return renderOk().add(data);
    }

    /**
     * 添加定时任务
     * @param job
     * @return
     */
    @RequestMapping(value = "/add",method = RequestMethod.POST)
    public ApiResult addJob(@ModelAttribute SysQuartzJob job){

        List<SysQuartzJob> list = quartzJobService.list(new QueryWrapper<SysQuartzJob>().lambda()
        .eq(SysQuartzJob::getJobClassName,job.getJobClassName()));
        if(list!=null&&list.size()>0){
            return renderError("该定时任务类名已存在");
        }
        add(job.getJobClassName(),job.getCronExpression(),job.getParameter());
        quartzJobService.save(job);
        return renderOk("创建定时任务成功");
    }

    /**
     * 更新定时任务
     * @param job
     * @return
     */
    @RequestMapping(value = "/edit",method = RequestMethod.POST)
    public ApiResult editJob(@ModelAttribute SysQuartzJob job){

        delete(job.getJobClassName());
        add(job.getJobClassName(),job.getCronExpression(),job.getParameter());
        job.setStatus(CommonConstant.STATUS_NORMAL);
        quartzJobService.updateById(job);
        return renderOk("更新定时任务成功");
    }

    /**
     * 暂停定时任务
     * @param job
     * @return
     */
    @RequestMapping(value = "/pause",method = RequestMethod.POST)
    public ApiResult pauseJob(@ModelAttribute SysQuartzJob job){

        try {
            scheduler.pauseJob(JobKey.jobKey(job.getJobClassName()));
        } catch (SchedulerException e) {
            throw new ApiException("暂停定时任务失败");
        }
        job.setStatus(CommonConstant.STATUS_DISABLE);
        quartzJobService.updateById(job);
        return renderOk("暂停定时任务成功");
    }

    /**
     * 恢复定时任务
     * @param job
     * @return
     */
    @RequestMapping(value = "/resume",method = RequestMethod.POST)
    public ApiResult resumeJob(@ModelAttribute SysQuartzJob job){

        try {
            scheduler.resumeJob(JobKey.jobKey(job.getJobClassName()));
        } catch (SchedulerException e) {
            throw new ApiException("恢复定时任务失败");
        }
        job.setStatus(CommonConstant.STATUS_NORMAL);
        quartzJobService.updateById(job);
        return renderOk("恢复定时任务成功");
    }

    /**
     * 删除定时任务
     * @param ids
     * @return
     */
    @RequestMapping(value = "/delByIds/{ids}",method = RequestMethod.DELETE)
    public ApiResult deleteJob(@PathVariable String[] ids){

        for(String id:ids){
            SysQuartzJob job = quartzJobService.getById(id);
            delete(job.getJobClassName());
            quartzJobService.removeById(job.getId());
        }
        return  renderOk("删除定时任务成功");
    }

    /**
     * 添加定时任务
     * @param jobClassName
     * @param cronExpression
     * @param parameter
     */
    public void add(String jobClassName, String cronExpression, String parameter){

        try {
            // 启动调度器
            scheduler.start();

            //构建job信息
            JobDetail jobDetail = JobBuilder.newJob(getClass(jobClassName).getClass())
                    .withIdentity(jobClassName)
                    .usingJobData("parameter",parameter)
                    .build();

            //表达式调度构建器(即任务执行的时间) 使用withMisfireHandlingInstructionDoNothing() 忽略掉调度暂停过程中没有执行的调度
            CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(cronExpression).withMisfireHandlingInstructionDoNothing();

            //按新的cronExpression表达式构建一个新的trigger
            CronTrigger trigger = TriggerBuilder.newTrigger().withIdentity(jobClassName)
                    .withSchedule(scheduleBuilder).build();

            scheduler.scheduleJob(jobDetail, trigger);
        } catch (SchedulerException e) {
            log.error(e.toString());
            throw new ApiException("创建定时任务失败");
        } catch (Exception e){
            throw new ApiException("后台找不到该类名任务");
        }
    }

    /**
     * 删除定时任务
     * @param jobClassName
     */
    public void delete(String jobClassName){

        try {
            scheduler.pauseTrigger(TriggerKey.triggerKey(jobClassName));
            scheduler.unscheduleJob(TriggerKey.triggerKey(jobClassName));
            scheduler.deleteJob(JobKey.jobKey(jobClassName));
        } catch (Exception e) {
            throw new ApiException("删除定时任务失败");
        }
    }

    public static Job getClass(String classname) throws Exception {
        Class<?> class1 = Class.forName(classname);
        return (Job)class1.newInstance();
    }

}
